<?php

namespace App\Services\Product\WeChatService;

use App\Exceptions\SystemException;
use App\Exceptions\WeChatException;
use App\Utils\WechatSdk\WeChatOperator;
use Cache;
use Carbon\Carbon;

class WeChatService {

    /**
     * 获取授权 code
     * @param  string $redirectUri 获取 code 之后跳转的 url
     * @return [type]              
     */
    public function getOAuthCode($redirectUri){
           return WeChatOperator::getOAuthCodeRedirectUrl($redirectUri);
    }

    /**
     * 获取 config 接口注入权限验证配置
     * @param  [type] $url 网址 url
     * @return [type]
     */
    public function getJssdkSignPackage($url){

        $jsapiTicket = $this->getJsapiTicketArray();

        if($jsapiTicket['errcode'] == 40001){
            $jsapiTicket = $this->getJsapiTicketArray(true);
        }

        $jsapiTicket = $jsapiTicket['ticket'];

        return WeChatOperator::getJssdkSignPackage($jsapiTicket, $url);
    }

    /**
     * 设置缓存
     * @param string  $key    缓存键名
     * @param mix     $value  缓存值
     */
    protected function setCache($key, $value){
        //缓存110 min
        $expiresAt = Carbon::now()->addMinutes(110);
        Cache::put($key, $value, $expiresAt);
    }

    /**
     * 获取 oAuthAccessToken
     * @param  string $code 授权 code
     * @return [type]       
     */
    public function oAuthAccessToken($code){
        $oAuthAccessToken = WeChatOperator::getOauthAccessToken($code);
        if(strpos($oAuthAccessToken->data, 'errcode')){
            return false;
        }
        return $oAuthAccessToken;
    }

    /**
     * 用户授权之后获得的用户信息
     * @param  string $oAuthAccessToken 
     * @return [type]                  
     */
    public function getUserInfo($oAuthAccessToken, $retry = true){

        $userInfo = WeChatOperator::getOAuthUserInfo($oAuthAccessToken->data);
        if(strpos($userInfo->data, 'errcode')){
            $oAuthAccessToken = WeChatOperator::refreshOAuthAccessToken($oAuthAccessToken->data);
            if(strpos($oAuthAccessToken->data, 'errcode')){
                // error data
                $errData = json_decode($userInfo->data, true);
                throw new WeChatException('invalid', "errcode:$errData[errcode] errmsg:$errData[errmsg]");
            }
            if($retry){

                $userInfo = $this->getUserInfo($oAuthAccessToken, false);
                return json_decode($userInfo->data, true);
            }
            throw new WeChatException('invalid', json_decode($userInfo->data, true)['errmsg']);

        }
        $userInfo = json_decode($userInfo->data, true);
        return $userInfo;
    }

    //获取 accessToken 调用接口凭证
    public function getAccessTokenArray($retrieve = false){
        if(!$retrieve && Cache::has('accessToken')){
        //不重新获取，缓存中有，从缓存中取
            $accessToken = Cache::get('accessToken');
        }else{
        //重新获取，或者缓存中没有
            $accessToken = WeChatOperator::getAccessToken();

            if(strpos($accessToken->data, 'errcode')){

                // logger(['accessToken' => $accessToken]);
                throw new SystemException('config', json_decode($accessToken->data, true)['errmsg']);
            }
            $this->setCache('accessToken', $accessToken);
        }
        return json_decode($accessToken->data, true);
    }

    //获取 jsapiTicket 数组
    public function getJsapiTicketArray($retrieve = false){

        if(!$retrieve && Cache::has('jsapiTicket')){
            $jsapiTicket = Cache::get('jsapiTicket');
        }else{
            //重新获取 jsapiticket
            $accessToken = $this->getAccessTokenArray()['access_token'];

            $jsapiTicket = WeChatOperator::getJsapiTicket($accessToken);
            
            //取得的 jsapiticket 是否正确。若access_token无效，则重新获取 accessToken 并重新获取 jsapiticket
            if(json_decode($jsapiTicket->data, true)['errcode'] == 40001){

                // logger(['jsapiTicket' => $jsapiTicket]);
                $accessToken = $this->getAccessTokenArray(true)['access_token'];

                $jsapiTicket = WeChatOperator::getJsapiTicket($accessToken);
            }
            $this->setCache('jsapiTicket', $jsapiTicket);
        }
        return json_decode($jsapiTicket->data, true);
    }

    //根据openid获取用户信息
    public function getUserInfoByOpenId($openId){
        $accessToken = $this->getAccessTokenArray()['access_token'];
        
        $result = WeChatOperator::getUserInfo($openId, $accessToken);
        if(strpos($result->data, 'errcode')){
            if(json_decode($result->data, true)['errcode'] == 40001){

                $accessToken = $this->getAccessTokenArray(true)['access_token'];

                return WeChatOperator::getUserInfo($openId, $accessToken);
            }
            throw new WeChatException('invalid', json_decode($result->data, true)['errmsg']);
        }
        return $result;
    }

    //微信公众号接入校验
    public function checkSignature($signature, $timestamp, $nonce){
        return WeChatOperator::checkSignature($signature, $timestamp, $nonce);
    }

    public function sendTemplateMessage($data){
            
        $accessToken = $this->getAccessTokenArray()['access_token'];
        $response = WeChatOperator::sendTemplateMessage($data, $accessToken);
        
        if(json_decode($response->data, true)['errcode'] == 40001){
            $accessToken = $this->getAccessTokenArray(true)['access_token'];
            WeChatOperator::sendTemplateMessage($data, $accessToken)->data;
        }
    }

    /**
     * 创建菜单
     * @return  
     */
    public function createMenu(){

        $accessToken = json_decode(WeChatOperator::getAccessToken()->data, true);
        $body = [
            "button" => [
                [
                "name" => "物联网", 
                "sub_button" => [
                    [
                        "type" => "view", 
                        "name" => "鹤庭水机管理", 
                        "url" => url("index")],
                    [
                        "type" => "view", 
                        "name" => "konka水机管理", 
                        "url" => url("device/index")],
                    [
                        "type" => "view", 
                        "name" => "我的水机", 
                       "url" => "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxae48f3bbcda86ab1&redirect_uri=http://test.dianqiukj.com/personal/waterindex&response_type=code&scope=snsapi_base&state=112233#wechat_redirect"],
                    ]
                ]
            ]
        ];

        dd(WeChatOperator::createMenu($body, $accessToken['access_token']));
    }



}
